﻿/*   
    Copyright (C) 2009 Galaktika Corporation ZAO

    This file is a part of Galaktika.BusinessMonitor
 
    Galaktika.BusinessMonitor is a free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
      
    You should have received a copy of the GNU General Public License
    along with Galaktika.BusinessMonitor.  If not, see <http://www.gnu.org/licenses/>.
  
    If GPL v.3 is not suitable for your products or company,
    Galaktika Corp provides Galaktika.BusinessMonitor under a flexible commercial license
    designed to meet your specific usage and distribution requirements.
    If you have already obtained a commercial license from Galaktika Corp,
    you can use this file under those license terms.
*/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Ranet.AgOlap.Controls.ContextMenu;

namespace Galaktika.BI.Silverlight.Controls
{
    using Galaktika.BI.Runtime;
    using Galaktika.BI.Runtime.Services;
    using Galaktika.BI.Extensibility.Dom;
    using Galaktika.BI.Silverlight.Intermediate;
    using Galaktika.BI.Silverlight.Services;
    using Ranet.AgOlap.Controls.General;

    public class LabelControl : UserControl, IBindableObject, IEditableObject
    {
        private SimpleTextBox txtBox;
        private ScrollViewer viewer;
       
        public LabelControl()
        {
            viewer = new ScrollViewer();
            viewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
            viewer.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled;
            txtBox = new SimpleTextBox();
            txtBox.IsTabStop = false;
            txtBox.IsReadOnly = true;
            txtBox.Cursor = Cursors.Arrow;
            this.AWordWrap = true;

            this.AHorzAlignment = HorzAlignment.Default;
            this.AVertAlignment = VertAlignment.Default;
            viewer.Content = txtBox;
            this.Content = viewer;            
            //this.Content = viewer;            
            this.viewer.AttachContextMenu(p => this.ContextMenu, ContextMenuSupportMode.OnCtrlLeftMouseButtonClick);
            this.viewer.AttachContextMenu(p => this.ContextMenu, ContextMenuSupportMode.OnRightMouseButtonClick);

            this.viewer.Style = Application.Current.Resources["LabelGlowStyle"] as Style;
           
           
        }


        protected virtual CustomContextMenu CreateContextMenu()
        {
            CustomContextMenu menu = new CustomContextMenu();
            var m_EnableSrolling = new ContextMenuItem(Galaktika.BI.Silverlight.Localization.Mnu_EnableScrolling);
            m_EnableSrolling.ItemClick += new EventHandler(m_EnableSrolling_ItemClick);
            menu.AddMenuItem(m_EnableSrolling);            
            return menu;
        }

        void m_EnableSrolling_ItemClick(object sender, EventArgs e)
        {
            this.AEnableScrolling = !this.AEnableScrolling;
            if (AEnableScrolling)
            {
                ((ContextMenuItem)sender).Icon = UriResources.Images.ActionNode16;
                EnableSrolling(true);
                return;
            }
            EnableSrolling(false);
            ((ContextMenuItem)sender).Icon = null;
        }

        private void EnableSrolling(bool result)
        {
            if (result)
            {
               viewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
               viewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;  
            }
            else
            {
                viewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
                viewer.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled;            
            }
        }

        private CustomContextMenu m_ContextMenu;
        protected CustomContextMenu ContextMenu
        {
            get
            {
                if (m_ContextMenu == null)
                {
                    m_ContextMenu = this.CreateContextMenu();
                }                
                return m_ContextMenu;
            }
        }

        private bool m_EnableScrolling;
        public bool AEnableScrolling
        {
            get { return m_EnableScrolling; }
            set { m_EnableScrolling = value; }
        }

        public bool AWordWrap
        {
            get;
            set;
        }

        public string AText
        {
            get;
            set;
        }

        public Color AForeColor { get; set; }

        public Color ABackColor { get; set; }

        public Color ABackColor2 { get; set; }

        public Font AFont { get; set; }

        public BorderStyles ABorderStyle { get; set; }

        public bool AShowToolTips { get; set; }

        public string AToolTipText { get; set; }

        public string AFormatScript { get; set; }

        public Cursor ACursor
        {
            get
            {
                return base.Cursor;
            }
            set
            {
                base.Cursor = value;
            }
        }

        public HorzAlignment AHorzAlignment { get; set; }

        public VertAlignment AVertAlignment { get; set; }

        #region IBindableObject Members

        public IBindingContext Context { get; set; }

        private IDictionary<string, IBindingManager> m_Bindings;
        public System.Collections.Generic.IDictionary<string, IBindingManager> Bindings
        {
            get
            {
                if (m_Bindings == null)
                {
                    m_Bindings = new SafeDictionary<string, IBindingManager>();
                }

                return m_Bindings;
            }
        }

        #endregion

        #region IEditableObject Members

        public void BeginEdit()
        {
            
        }

        public void CancelEdit()
        {            
        }

        public void EndEdit()
        {
            if (this.AWordWrap)
            {
                txtBox.TextWrapping = TextWrapping.Wrap;
            }
            else
            {
                txtBox.TextWrapping = TextWrapping.NoWrap;
            }
            EnableSrolling(this.AEnableScrolling);
            if (this.AFont != null)
            {
                txtBox.FontFamily = new FontFamily(this.AFont.FamilyName);
                txtBox.FontSize = this.AFont.Size;
                if (this.AFont.Italic)
                {
                    txtBox.FontStyle = FontStyles.Italic;
                }
                if (this.AFont.Bold)
                {
                    txtBox.FontWeight = FontWeights.Bold;
                }
            }
            Color emptyColor = Color.FromArgb(0, 0, 0, 0);
            if (this.AForeColor != emptyColor)
            {
                txtBox.Foreground = new SolidColorBrush(this.AForeColor);
            }
            if (this.ABackColor != emptyColor)
            {
                if (this.ABackColor2 != emptyColor)
                {
                    GradientStopCollection coll = new GradientStopCollection();
                    coll.Add(new GradientStop() { Color = this.ABackColor });
                    coll.Add(new GradientStop() { Color = this.ABackColor2, Offset = 1 });
                    txtBox.Background = new LinearGradientBrush(coll, 45.0);
                }
                else
                {
                    txtBox.Background = new SolidColorBrush(this.ABackColor);
                }
            }

            //base.Background = new SolidColorBrush(Colors.Magenta);

            switch (this.ABorderStyle)
            {
                case BorderStyles.HotFlat:
                case BorderStyles.Flat:
                case BorderStyles.NoBorder:
                    txtBox.BorderThickness = new Thickness(0.0);
                    break;
                default:
                    break;

            }

            switch (this.AVertAlignment)
            {
                case VertAlignment.Center:
                    txtBox.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                    break;
                case VertAlignment.Bottom:
                    txtBox.VerticalAlignment = System.Windows.VerticalAlignment.Bottom;
                    break;
                case VertAlignment.Top:
                    txtBox.VerticalAlignment = System.Windows.VerticalAlignment.Top;
                    break;
            }
            switch (this.AHorzAlignment)
            {
                case HorzAlignment.Center:
                    txtBox.TextAlignment = TextAlignment.Center;
                    break;
                case HorzAlignment.Near:
                    txtBox.TextAlignment = TextAlignment.Left;
                    break;
                case HorzAlignment.Far:
                    txtBox.TextAlignment = TextAlignment.Right;
                    break;
            }

            if (ScriptEngine.ContainsExpression(this.AText) ||
                (this.AShowToolTips && ScriptEngine.ContainsExpression(this.AToolTipText)))
            {
                IUserTaskManager taskMgr = (IUserTaskManager)this.Context.Services.GetService(typeof(IUserTaskManager));
                IExecutionContext exe = (IExecutionContext)this.Context.Services.GetService(typeof(IExecutionContext));
                if (taskMgr != null && exe != null)
                {
                    taskMgr.RunTaskAsync(string.Format(Galaktika.BI.Silverlight.Localization.AppTask_ProcessingProperties, base.Name),
                        state =>
                        {
                            string text = exe.Parse(this.Context, this.AText);
                            string tooltip = exe.Parse(this.Context, this.AToolTipText);

                            if (!string.IsNullOrEmpty(this.AFormatScript))
                            {
                                this.DoCusomFomatting(ref text);
                            }

                            taskMgr.Dispatcher.BeginInvoke(() =>
                            {
                                txtBox.Text = text;
                                if (this.AShowToolTips && !string.IsNullOrEmpty(tooltip))
                                {
                                    ToolTipService.SetToolTip(this, new StyledToolTip() { Content = tooltip });
                                }
                            });
                        });
                }
            }
            else
            {
                var text = this.AText;
                if (!string.IsNullOrEmpty(this.AFormatScript))
                {
                    this.DoCusomFomatting(ref text);
                }
                txtBox.Text = text;
                this.IsEnabled = true;
                if (this.AShowToolTips && !string.IsNullOrEmpty(this.AToolTipText))
                {
                    ToolTipService.SetToolTip(this, new StyledToolTip() { Content = this.AToolTipText });
                }
            }
        }
        
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();                                 
        }

        private void DoCusomFomatting(ref string text)
        {
            IAppManager app = (IAppManager)this.Context.Services.GetService(typeof(IAppManager));
            if (app != null)
            {
                string script = string.Format("{0}(\"{1}\")", this.AFormatScript, text);
                FuncInvokeCheckResult check = ScriptEngine.CheckFuncInvoke(script);
                if (check.IsSuccess)
                {
                    try
                    {
                        text = ScriptEngine.InvokeFunction(this.Context, check, app.ClientAssembly);
                    }
                    catch (Exception exc)
                    {
                        text = exc.ToString();
                    }
                }
            }
        }

        #endregion
    }
}
